package thesis;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;

import de.bwaldvogel.liblinear.Predict;

public class ThesisHAH {

	/**
	 * @param args
	 * @throws IOException 
	 */
	public static void main(String[] args) throws IOException {
		// label of classes
		ArrayList<String> label = new ArrayList<String>();
		label.add("1");
		label.add("2");
		label.add("3");
		label.add("4");
		label.add("5");

		// number of models
		ArrayList<String> model = new ArrayList<String>();
		model.add("1_2");
		model.add("4_5");
		model.add("1_2_3_4_5");
		
		String fileTestName = "1_2.test"; //test file which contains 1 or a lot of test file in LibSVM format


		// array of original file to array to check accuracy
		ArrayList<String> accuracyTrain = new ArrayList<String>();
		// array of classified file to array to check accuracy
		ArrayList<String> accuracyTest = new ArrayList<String>();
		
		//read file contains 1 or a lot of test file in LibSVM format
		ArrayList<String> fileNames = new ArrayList<String>();
		System.out.println(readArrayFile(fileTestName));
		fileNames.addAll(readArrayFile(fileTestName));
		
		ArrayList<String> currentLabels = new ArrayList<String>();
		currentLabels.addAll(label);

		String[] predictArg = new String[4]; 
		predictArg[0] = fileTestName;
		predictArg[1] = "1_2_3_4_5.train.model";
		predictArg[2] = "1_2.out";
		predictArg[3] = "1";
		
		ArrayList<String> class1 = new ArrayList<String>();
		ArrayList<String> class2 = new ArrayList<String>();
		System.out.println("fileNames.size() : " + fileNames.size());
		for(int i = 0; i < fileNames.size(); i++){ //fileNames.size()
			System.out.println("fileNames : " + (i+1) + " " + "---------------------------------");
			String orginalLabel = fileNames.get(i);
			String predictedLabel = null;
			
			if(orginalLabel.contains(" ")){
				accuracyTrain.add(orginalLabel.split(" ")[0]);
			} else {
				accuracyTrain.add(orginalLabel);
			}
			
			ArrayList<String> tempCurrentLabels = new ArrayList<String>();
			tempCurrentLabels.addAll(currentLabels);
			
			//while number of labels is bigger than 2, separate it to class1 and class2
			while(tempCurrentLabels.size() > 1){
//				System.out.println("currentLabels1 : " + tempCurrentLabels);
				if(tempCurrentLabels.size() == 2){
					String[] predictArg2 = new String[4];
					Predict predict = new Predict();
					predict.predictLabelArray.clear();
					
					predictArg2[0] = fileTestName; //not necessary
					predictArg2[1] = tempCurrentLabels.get(0) + "_" + tempCurrentLabels.get(1) + ".train.model";
					predictArg2[2] = "out"; //not necessary
					predictArg2[3] = "2"; 
					System.out.println("model : " + tempCurrentLabels.get(0) + "_" + tempCurrentLabels.get(1) + ".train.model");
					
					predict.singleFile = fileNames.get(i);
					predict.main(predictArg2);
					predictedLabel = predict.getPredictLabelArray().get(0).toString();
					
					accuracyTest.add(predictedLabel);
					
					tempCurrentLabels.clear();
				} else {
					for(int j = 0; j < tempCurrentLabels.size(); j++) {
						if(j < tempCurrentLabels.size()/2){
							class1.add(tempCurrentLabels.get(j));
						} else {
							class2.add(tempCurrentLabels.get(j));
						}
					}
					System.out.println("class1 : " + class1);
					System.out.println("class2 : " + class2);
					String modelArg = "";
					for(int k = 0; k < tempCurrentLabels.size(); k++){
						modelArg += tempCurrentLabels.get(k) + "_";
					}
					
					String[] predictArg2 = new String[4];
					Predict predict = new Predict();
					predict.predictLabelArray.clear();
					
					predictArg2[0] = fileTestName; //not necessary
					predictArg2[1] = modelArg.substring(0, modelArg.length() - 1) + ".train.model";
					predictArg2[2] = "out"; //not necessary
					predictArg2[3] = "2"; 
					System.out.println("model : " + modelArg.substring(0, modelArg.length() - 1) + ".train.model");
					System.out.println("orginalLabel1 : " + orginalLabel);
					//change label of file to 1 if belong to class1, 2 if belong to class2
					if(orginalLabel.contains(" ")){
						if(class1.contains(orginalLabel.split(" ")[0])){
							orginalLabel = 1 + orginalLabel.substring(orginalLabel.indexOf(" "), orginalLabel.length());
						}
						if(class2.contains(orginalLabel.split(" ")[0])){
							orginalLabel = 2 + orginalLabel.substring(orginalLabel.indexOf(" "), orginalLabel.length());
						}
					} else { // if label without content
						if(class1.contains(orginalLabel)){
							orginalLabel = 1 + "";
						}
						if(class2.contains(orginalLabel)){
							orginalLabel = 2 + "";
						}
					}
					System.out.println("orginalLabel2 : " + orginalLabel);
//					System.out.println("orginalLabel.charAt(0) : " + orginalLabel.charAt(0));
					if('1' == orginalLabel.charAt(0) | '2' == orginalLabel.charAt(0)){
						predict.singleFile = orginalLabel;
//						System.out.println("predict.singleFile : " + predict.singleFile);						
						predict.main(predictArg2);
//						System.out.println("predict.getPredictLabelArray() : " + predict.getPredictLabelArray());
//						System.out.println("predict.getPredictLabelArray().get(0) : " + predict.getPredictLabelArray().get(0));
						if(predict.getPredictLabelArray().get(0) == 1){
							tempCurrentLabels.clear();
							tempCurrentLabels.addAll(class1);							
						}
						if(predict.getPredictLabelArray().get(0) == 2){
							tempCurrentLabels.clear();
							tempCurrentLabels.addAll(class2);
						}
//						System.out.println("currentLabels2 : " + tempCurrentLabels);
						if(class1.size() == 1 && predict.getPredictLabelArray().get(0) == 1){
							predictedLabel = class1.get(0);
							accuracyTest.add(fileNames.get(i).substring(0, 1));
//							System.out.println("fileNames.get(i).substring(0, 1) : " + fileNames.get(i).substring(0, 1));
						} 
						class1.clear();
						class2.clear();		
						
					} else {
						tempCurrentLabels.clear();
					}
				}			
				
			}			
		}		
		
		System.out.println("accuracyTrain.size(): " + accuracyTrain.size());
		System.out.println("accuracyTest.size(): " + accuracyTest.size());
		double accuracy = 0;
		int countAccuracy = 0;
		// if(accuracyTest.size() == accuracyTrain.size()){
		for (int i = 0; i < accuracyTest.size(); i++) {
			System.out.println("accuracyTrain +  accuracyTest: "
					+ accuracyTrain.get(i) + "+" + accuracyTest.get(i));
			if (accuracyTrain.get(i).equals(accuracyTest.get(i))) {
				countAccuracy++;
			}
		}
		accuracy = countAccuracy / accuracyTest.size();
		System.out.println("countAccuracy: " + countAccuracy);
		System.out.println("Do chinh xac: " + accuracy);

	}
	
	// read before oue file to get current label, then add next label to get
		// exactly 2 label which is need to be classify
		static String getModel(String testFileName){
			String temp = "";
			try (BufferedReader br = new BufferedReader(new FileReader(testFileName))) {
				String sCurrentLine;
				while ((sCurrentLine = br.readLine()) != null) {
					temp += sCurrentLine;
					temp = temp.substring(0,1);
					break;
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
			System.out.println("Label: " + temp);

			return temp;
		}

		static String readFile(String fileName) {
			String temp = "";
			try (BufferedReader br = new BufferedReader(new FileReader(fileName))) {
				String sCurrentLine;
				while ((sCurrentLine = br.readLine()) != null) {
					temp += sCurrentLine + "\n";
				}
			} catch (IOException e) {
				e.printStackTrace();
			}

			return temp;
		}
		
		static void writeFile(String fileName, String writeString) {
			try {
				File fileDir = new File(fileName);
				BufferedWriter out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(fileDir), "UTF8"));
				
				out.append(writeString);
				
				out.flush();
				out.close();
			} catch (UnsupportedEncodingException e) {
				System.out.println(e.getMessage());
			} catch (IOException e) {
				System.out.println(e.getMessage());
			} catch (Exception e) {
				System.out.println(e.getMessage());
			}
		}
		
		static ArrayList<String> readArrayFile(String fileName) {
			ArrayList<String> temp = new ArrayList<String>();
			try (BufferedReader br = new BufferedReader(new FileReader(fileName))) {
				String sCurrentLine;
				while ((sCurrentLine = br.readLine()) != null) {
					temp.add(sCurrentLine);
				}
			} catch (IOException e) {
				e.printStackTrace();
			}

			return temp;
		}

}
